/*
 *  Copyright 2010 UPF Telecos 4th group G.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package edu.upf.database.impl;

import edu.upf.core.ClientLogic;
import edu.upf.database.DBAction;
import edu.upf.database.DBActionResult;
import edu.upf.database.DBManager;
import edu.upf.messages.SearchResult;
import edu.upf.utils.Definitions;
import edu.upf.exceptions.DBConnectionFailed;
import java.io.IOException;

/**
 * <p>Encapsulates the database acces by providing methods for executing the
 * different queries</p>
 * @author netjois
 */
public class MediaDAO implements Definitions {

    private DBManager db;
    private DBAction action;
    private DBActionResult dbResult;
    private SearchResult searchResult;
    private ClientLogic clientLogic;
    private static MediaDAO dao;

    /**
     * Constructor, initializes the database access. Receives the ClientLogic
     * object for callback purposes
     * @param clientLogic
     */
    private MediaDAO(ClientLogic clientLogic) {
        try {
            db = DBManagerImpl.getInstance();
            this.clientLogic = clientLogic;

        } catch (DBConnectionFailed ex) {
            /*Por el momento tratamos igual todas las excepciones, más adelante
            si es necesario se pueden distinguir en diferentes catch segun el
            nivel de gravedad o tratamiento necesario*/
            clientLogic.showExceptionMessage(ex, WARNING);
        } catch (IOException ex) {
            clientLogic.showExceptionMessage(ex, ERROR);
        }
    }

    public static synchronized MediaDAO getInstance(ClientLogic clientLogic) {
        if (dao == null) {
            dao = new MediaDAO(clientLogic);
        }
        return dao;
    }

    /**
     * Performs a keyword search for image and video
     * @param queryParam
     * @return
     */
    public SearchResult basicAllSearch(String[] queryParam) {
        searchResult = new SearchResult(queryParam[FREE_TEXT_POS]);
        genericQuery(QUERY_IMAGE_BASIC, queryParam);
        genericQuery(QUERY_VIDEO_BASIC, queryParam);
        return searchResult;
    }

    /**
     * Performs a keyword search for image
     * @param queryParam
     * @return
     */
    public SearchResult basicImageSearch(String[] queryParam) {
        searchResult = new SearchResult(queryParam[FREE_TEXT_POS]);
        genericQuery(QUERY_IMAGE_BASIC, queryParam);
        return searchResult;
    }

    /**
     * Performs a keyword search for video
     * @param queryParam
     * @return
     */
    public SearchResult basicVideoSearch(String[] queryParam) {
        searchResult = new SearchResult(queryParam[FREE_TEXT_POS]);
        genericQuery(QUERY_VIDEO_BASIC, queryParam);
        return searchResult;
    }

    /**
     * Performs a category search for image and video
     * @param queryParam
     * @return
     */
    public SearchResult categorySearch(String[] queryParam) {

        if (queryParam.length == 1) {
            searchResult = new SearchResult(queryParam[FREE_TEXT_POS]);
            genericQuery(QUERY_IMAGE_CATEGORY, queryParam);
            genericQuery(QUERY_VIDEO_CATEGORY, queryParam);
        } else if (queryParam.length >= 2) {
            searchResult = new SearchResult(queryParam[CATEGORY_POS] + SPLITTER
                    + queryParam[SEARCH_POS]);
            genericQuery(QUERY_IMAGE_CATEGORYPLUS, queryParam);
            genericQuery(QUERY_VIDEO_CATEGORYPLUS, queryParam);
        }
        return searchResult;
    }

    /**
     * Performs an article search for image and video
     * @param queryParam
     * @return
     */
    public SearchResult articleSearch(String[] queryParam) {
        searchResult = new SearchResult(queryParam[FREE_TEXT_POS]);
        genericQuery(QUERY_IMAGE_ARTICLE, queryParam);
        genericQuery(QUERY_VIDEO_ARTICLE, queryParam);
        return searchResult;
    }

    /**
     * Performs a title search for image and video
     * @param queryParam
     * @return
     */
    public SearchResult titleSearch(String[] queryParam) {
        searchResult = new SearchResult(queryParam[FREE_TEXT_POS]);
        genericQuery(QUERY_IMAGE_TITLE, queryParam);
        genericQuery(QUERY_VIDEO_TITLE, queryParam);
        return searchResult;
    }

    /**
     * Performs a paragraph search for image and video
     * @param queryParam
     * @return
     */
    public SearchResult paragraphSearch(String[] queryParam) {
        searchResult = new SearchResult(queryParam[FREE_TEXT_POS]);
        genericQuery(QUERY_IMAGE_PARAGRAPH, queryParam);
        genericQuery(QUERY_VIDEO_PARAGRAPH, queryParam);
        return searchResult;
    }

    public SearchResult getAlbums() {
        searchResult = new SearchResult("retrieve.content");
        genericQuery(RETRIEVE_IMAGE_ALBUMS, new String[]{""});
        genericQuery(RETRIEVE_VIDEO_ALBUMS, new String[]{""});
        return searchResult;
    }

    /**
     * Returns a result with all the current shared videos
     * @return
     */
    public SearchResult getSharedVideos() {
        searchResult = new SearchResult(RETRIEVE_VIDEO);
        genericQuery(RETRIEVE_VIDEO, new String[]{""});
        return searchResult;
    }

    /**
     * Returns a result with all the current shared videos
     * @return
     */
    public SearchResult getSharedImages() {
        searchResult = new SearchResult(RETRIEVE_IMAGES);
        genericQuery(RETRIEVE_IMAGES, new String[]{""});
        return searchResult;
    }

    /**
     * Returns a result with all the current shared videos
     * @return
     */
    public SearchResult getSharedContent() {
        searchResult = new SearchResult("retrieve.content");
        genericQuery(RETRIEVE_IMAGES, new String[]{""});
        genericQuery(RETRIEVE_VIDEO, new String[]{""});
        return searchResult;
    }

    /**
     * Returns a result with all the current shared videos
     * @param directory
     * @return
     */
    public SearchResult getPathContent(String directory) {
        searchResult = new SearchResult("retrieve.content." + directory);
        genericQuery(RETRIEVE_IMAGE_PATH, new String[]{directory});
        genericQuery(RETRIEVE_VIDEO_PATH, new String[]{directory});
        return searchResult;
    }

    public boolean addImageTag(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_IMAGE_TAG);
        genericQuery(UPDATE_IMAGE_TAG, queryParam);
        return true;
    }

    public boolean addVideoTag(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_VIDEO_TAG);
        genericQuery(UPDATE_VIDEO_TAG, queryParam);
        return true;
    }

    public boolean updateImageCategory(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_IMAGE_CATEGORY);
        genericQuery(UPDATE_IMAGE_CATEGORY, queryParam);
        return true;
    }

    public boolean updateVideoCategory(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_VIDEO_CATEGORY);
        genericQuery(UPDATE_VIDEO_CATEGORY, queryParam);
        return true;
    }

    public boolean updateImageAlbum(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_IMAGE_ALBUM);
        genericQuery(UPDATE_IMAGE_ALBUM, queryParam);
        return true;
    }

    public boolean updateVideoAlbum(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_VIDEO_ALBUM);
        genericQuery(UPDATE_VIDEO_ALBUM, queryParam);
        return true;
    }

    public boolean deleteImage(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_DEL_IMAGE);
        genericQuery(UPDATE_DEL_IMAGE, queryParam);
        return true;
    }

    public boolean deleteVideo(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_DEL_VIDEO);
        genericQuery(UPDATE_DEL_VIDEO, queryParam);
        return true;
    }

    public boolean changeAlbum(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_ALBUMS_IMAGE);
        genericQuery(UPDATE_ALBUMS_IMAGE, queryParam);
        genericQuery(UPDATE_ALBUMS_VIDEO, queryParam);
        return true;
    }

    public boolean deleteAlbum(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_DEL_IMAGE_ALBUM);
        genericQuery(UPDATE_DEL_IMAGE_ALBUM, queryParam);
        genericQuery(UPDATE_DEL_VIDEO_ALBUM, queryParam);
        return true;
    }

    public boolean addImage(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_NEW_IMAGE);
        genericQuery(UPDATE_NEW_IMAGE, queryParam);
        return true;
    }

    public boolean addVideo(String[] queryParam) {
        searchResult = new SearchResult(UPDATE_NEW_VIDEO);
        genericQuery(UPDATE_NEW_VIDEO, queryParam);
        return true;
    }
    //Performs a query with the given parameters

    private void genericQuery(String query, String[] queryParam) {

        action = new DBActionImpl(query, queryParam);
        dbResult = (DBActionResult) db.execute(action);

        if (dbResult.isOk()) {
            if (searchResult.getList() == null) {
                searchResult.setList(dbResult.getResult());
            } else {
                searchResult.addList(dbResult.getResult());
            }
        } else {
            clientLogic.showExceptionMessage(dbResult.getException(), ERROR);
        }
    }
}
